"""
-*- coding: utf-8 -*-
@Author  : Link
@Time    : 2022/11/25 15:04
@Site    : 
@File    : log_utils.py
@Software: PyCharm
@Remark  : 
"""

from loguru import logger
from functools import wraps

from prettytable import PrettyTable
import datetime as dt

from BenchCore.stdf_interface.stdf_def_interface import Mir
from BenchUtils.func import timestamp_to_str2


def singleton_class_decorator(cls):
    """
    装饰器，单例类的装饰器
    """
    # 在装饰器里定义一个字典，用来存放类的实例。
    _instance = {}

    # 装饰器，被装饰的类
    @wraps(cls)
    def wrapper_class(*args, **kwargs):
        # 判断，类实例不在类实例的字典里，就重新创建类实例
        if cls not in _instance:
            # 将新创建的类实例，存入到实例字典中
            _instance[cls] = cls(*args, **kwargs)
        # 如果实例字典中，存在类实例，直接取出返回类实例
        return _instance[cls]

    # 返回，装饰器中，被装饰的类函数
    return wrapper_class


@singleton_class_decorator
class Logger:
    def __init__(self, path="lgr.log", ):
        self.path = path
        self.logger_add()

    def logger_add(self):
        logger.add(
            # 水槽，分流器，可以用来输入路径
            sink=self.path,
            # 日志创建周期
            # rotation='00:00',
            # 保存
            retention='60 days',
            # 文件的压缩格式
            # compression='zip',
            # 编码格式
            encoding="utf-8",
            # 具有使日志记录调用非阻塞的优点
            enqueue=True
        )

    @property
    def get_logger(self):
        return logger


class LPrint:
    INFO = "INF"
    ERROR = "ERR"
    WARNING = "WAR"
    DEBUG = "DEB"
    SUCCESS = "SUC"


class Print:
    """
    全局Logger
    """
    DEBUG = True
    STOP = False

    @staticmethod
    def PrintTable(data_list: list):
        table = PrettyTable()
        # table.title = 'Calculation Ptr'
        for index, each in enumerate(data_list):
            if not isinstance(each, dict):
                each = dict(each)
            if index == 0:
                table.field_names = each.keys()
            table.add_row(each.values())
        Print.Warning('\r\n' + str(table))

    @staticmethod
    def PrintTableString(data_list: list):
        table = PrettyTable()
        # table.title = 'Calculation Ptr'
        for index, each in enumerate(data_list):
            if not isinstance(each, dict):
                each = dict(each)
            if index == 0:
                table.field_names = each.keys()
            table.add_row(each.values())
        return str(table)

    @staticmethod
    def Info(string):
        if Print.STOP:
            return
        if Print.DEBUG:
            # print("[{}][{}]{}".format(LPrint.INFO, dt.datetime.now().strftime("%H:%M:%S"), string))
            return
        logger.info(string)

    @staticmethod
    def Debug(string):
        if Print.STOP:
            return
        if Print.DEBUG:
            print("[{}][{}]{}".format(LPrint.DEBUG, dt.datetime.now().strftime("%H:%M:%S"), string))
            return
        # logger.debug(string)

    @staticmethod
    def Record(string):
        if Print.STOP:
            return
        if Print.DEBUG:
            # print("[{}][{}]{}".format(LPrint.INFO, dt.datetime.now().strftime("%H:%M:%S"), string))
            return
        logger.info(string)

    @staticmethod
    def Success(string):
        if Print.STOP:
            return
        if Print.DEBUG:
            # print("[{}][{}]{}".format(LPrint.SUCCESS, dt.datetime.now().strftime("%H:%M:%S"), string))
            return
        logger.success(string)

    @staticmethod
    def Warning(string):
        # if Print.STOP:
        #     return
        if Print.DEBUG:
            print("[{}][{}]{}".format(LPrint.WARNING, dt.datetime.now().strftime("%H:%M:%S"), string))
            return
        logger.warning(string)

    @staticmethod
    def Danger(string):
        if Print.STOP:
            return
        if Print.DEBUG:
            # print("[{}][{}]{}".format(LPrint.ERROR, dt.datetime.now().strftime("%H:%M:%S"), string))
            return
        logger.error(string)

    @staticmethod
    def Error(string):
        if Print.DEBUG:
            print("[{}][{}]{}".format(LPrint.ERROR, dt.datetime.now().strftime("%H:%M:%S"), string))
            return
        logger.error(string)

    @staticmethod
    def PASS(dut: int = None):
        if dut is None:
            dut_str = ''
        else:
            dut_str = "SITE:{} ".format(dut)
        Print.Success(dut_str + """
******************************************
******  @@@@     @    @@@@@  @@@@@  ******
******  @   @   @ @   @      @      ******
******  @@@@   @@@@@  @@@@@  @@@@@  ******
******  @      @   @      @      @  ******
******  @      @   @  @@@@@  @@@@@  ******
******************************************
        """)

    @staticmethod
    def FAIL(dut: int = None):
        if dut is None:
            dut_str = ''
        else:
            dut_str = "SITE:{} ".format(dut)
        Print.Warning(dut_str + """
******************************************
******  @@@@@    @      @    @      ******
******  @       @ @     @    @      ******
******  @@@@@  @@@@@    @    @      ******
******  @      @   @    @    @      ******
******  @      @   @    @    @@@@@  ******
******************************************
        """)

    @staticmethod
    def LOT_INFO(mir: Mir, string=False):
        message = """
******************************************
SETUP_T:{SETUP_T}  // Setup时间
START_T:{START_T}  // 开始测试时间
STAT_NUM:{STAT_NUM}
MODE_COD:{MODE_COD}  // 测试类型-> 量产 P, 工程 E
LOT_ID:{LOT_ID}  // 客户工单
PART_TYP:{PART_TYP}  // 产品型号
NODE_NAM:{NODE_NAM}  // Ate名字
JOB_NAM:{JOB_NAM}  // 程序名
SBLOT_ID:{SBLOT_ID}  // 工厂工单
FLOW_ID:{FLOW_ID}  // 复测类型 -> R0, R1
TEST_COD:{TEST_COD}  // 测试站点 -> CP/FT/SLT
TST_TEMP:{TST_TEMP}  // 测试温度 -> 25/85
******************************************
                """.format(
            SETUP_T=timestamp_to_str2(mir.SETUP_T),
            START_T=timestamp_to_str2(mir.START_T),
            STAT_NUM=mir.STAT_NUM,
            MODE_COD=mir.MODE_COD,
            LOT_ID=mir.LOT_ID,
            PART_TYP=mir.PART_TYP,
            NODE_NAM=mir.NODE_NAM,
            JOB_NAM=mir.JOB_NAM,
            SBLOT_ID=mir.SBLOT_ID,
            FLOW_ID=mir.FLOW_ID,
            TEST_COD=mir.TEST_COD,
            TST_TEMP=mir.TST_TEMP,
        )
        if string:
            return message
        Print.Success(message)


if __name__ == '__main__':
    Print.PASS()
